home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / Mesa-3.0 / SRC / FX / FXWGL.C < prev   
Encoding:
C/C++ Source or Header  |  1998-09-18  |  20.3 KB  |  803 lines

  1. /* fxwgl.c - Microsoft wgl functions emulation for
  2.  *           3Dfx VooDoo/Mesa interface
  3.  */
  4.  
  5. /*
  6.  * This library is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Library General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * This library is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Library General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Library General Public
  17.  * License along with this library; if not, write to the Free
  18.  * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  * See the file fxapi.c for more informations about authors
  21.  *
  22.  */
  23.  
  24. #ifdef __WIN32__
  25.  
  26. #ifdef __cplusplus
  27. extern "C" {
  28. #endif
  29.  
  30. #include <GL/gl.h>
  31. #include <GL/glu.h>
  32.  
  33. #ifdef __cplusplus
  34. }
  35. #endif
  36.  
  37. #include <stdio.h>
  38. #include <windows.h>
  39.  
  40. #include <GL/fxmesa.h>
  41.  
  42. #include "fxdrv.h"
  43.  
  44. #define MAX_MESA_ATTRS  20
  45.  
  46. struct __extensions__
  47. {
  48.   PROC  proc;
  49.   char  *name;
  50. };
  51.  
  52. struct __pixelformat__
  53. {
  54.   PIXELFORMATDESCRIPTOR pfd;
  55.   GLint mesaAttr[MAX_MESA_ATTRS];
  56. };
  57.  
  58. WINGDIAPI void APIENTRY gl3DfxSetPaletteEXT(GLuint *);
  59.  
  60. static struct __extensions__   ext[] = {
  61.  
  62. #ifdef GL_EXT_polygon_offset
  63.   {     (PROC)glPolygonOffsetEXT,               "glPolygonOffsetEXT"                    },
  64. #endif
  65.   {     (PROC)glBlendEquationEXT,               "glBlendEquationEXT"                    },
  66.   {     (PROC)glBlendColorEXT,                  "glBlendColorExt"                       },
  67.   {     (PROC)glVertexPointerEXT,               "glVertexPointerEXT"                    },
  68.   {     (PROC)glNormalPointerEXT,               "glNormalPointerEXT"                    },
  69.   {     (PROC)glColorPointerEXT,                "glColorPointerEXT"                     },
  70.   {     (PROC)glIndexPointerEXT,                "glIndexPointerEXT"                     },
  71.   {     (PROC)glTexCoordPointerEXT,             "glTexCoordPointer"                     },
  72.   {     (PROC)glEdgeFlagPointerEXT,             "glEdgeFlagPointerEXT"                  },
  73.   {     (PROC)glGetPointervEXT,                 "glGetPointervEXT"                      },
  74.   {     (PROC)glArrayElementEXT,                "glArrayElementEXT"                     },
  75.   {     (PROC)glDrawArraysEXT,                  "glDrawArrayEXT"                        },
  76.   {     (PROC)glAreTexturesResidentEXT,        "glAreTexturesResidentEXT"              },
  77.   {     (PROC)glBindTextureEXT,                 "glBindTextureEXT"                      },
  78.   {     (PROC)glDeleteTexturesEXT,              "glDeleteTexturesEXT"                   },
  79.   {     (PROC)glGenTexturesEXT,                 "glGenTexturesEXT"                      },
  80.   {     (PROC)glIsTextureEXT,                   "glIsTextureEXT"                        },
  81.   {     (PROC)glPrioritizeTexturesEXT,        "glPrioritizeTexturesEXT"               },
  82.   {     (PROC)glCopyTexSubImage3DEXT,        "glCopyTexSubImage3DEXT"                },
  83.   {     (PROC)glTexImage3DEXT,                  "glTexImage3DEXT"                       },
  84.   {     (PROC)glTexSubImage3DEXT,               "glTexSubImage3DEXT"                    },
  85.   {     (PROC)gl3DfxSetPaletteEXT,              "3DFX_set_global_palette"               }
  86.   /*
  87.   ,{     (PROC)glSelectTextureSGIS,              "glSelectTextureSGIS"                   },
  88.   {     (PROC)glMultiTexCoord2fSGIS,            "glMTexCoord2fSGIS"                     },
  89.   {     (PROC)glMultiTexCoord2fvSGIS,           "glMTexCoord2fvSGIS"                    }
  90.   */
  91. };
  92.  
  93. static int qt_ext = sizeof(ext) / sizeof(ext[0]);
  94.  
  95. struct __pixelformat__  pix[] =
  96. {
  97.   /* None */
  98.   {
  99.     {
  100.       sizeof(PIXELFORMATDESCRIPTOR),  1,
  101.       PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
  102.       PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
  103.       PFD_TYPE_RGBA,
  104.       32,
  105.       8,0,8,8,8,16,0,24,
  106.       0,0,0,0,0,
  107.       0,
  108.       0,
  109.       0,
  110.       PFD_MAIN_PLANE,
  111.       0,0,0,0
  112.     },
  113.     {
  114.       FXMESA_DOUBLEBUFFER,
  115.       FXMESA_ALPHA_SIZE,      0,
  116.       FXMESA_DEPTH_SIZE,      0,
  117.       FXMESA_STENCIL_SIZE,    0,
  118.       FXMESA_ACCUM_SIZE,      0,
  119.       FXMESA_NONE
  120.     }
  121.   },
  122.  
  123.   /* Alpha */
  124.   {
  125.     {
  126.       sizeof(PIXELFORMATDESCRIPTOR),  1,
  127.       PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
  128.       PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
  129.       PFD_TYPE_RGBA,
  130.       32,
  131.       8,0,8,8,8,16,8,24,
  132.       0,0,0,0,0,
  133.       0,
  134.       0,
  135.       0,
  136.       PFD_MAIN_PLANE,
  137.       0,0,0,0
  138.     },
  139.     {
  140.       FXMESA_DOUBLEBUFFER,
  141.       FXMESA_ALPHA_SIZE,      8,
  142.       FXMESA_DEPTH_SIZE,      0,
  143.       FXMESA_STENCIL_SIZE,    0,
  144.       FXMESA_ACCUM_SIZE,      0,
  145.       FXMESA_NONE
  146.     }
  147.   },
  148.  
  149.   /* Depth */
  150.   {
  151.     {
  152.       sizeof(PIXELFORMATDESCRIPTOR),  1,
  153.       PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
  154.       PFD_DOUBLEBUFFER|PFD_SWAP_COPY,
  155.       PFD_TYPE_RGBA,
  156.       32,
  157.       8,0,8,8,8,16,0,24,
  158.       0,0,0,0,0,
  159.       16,
  160.       0,
  161.       0,
  162.       PFD_MAIN_PLANE,
  163.       0,0,0,0
  164.     },
  165.     {
  166.       FXMESA_DOUBLEBUFFER,
  167.       FXMESA_ALPHA_SIZE,      0,
  168.       FXMESA_DEPTH_SIZE,      16,
  169.       FXMESA_STENCIL_SIZE,    0,
  170.       FXMESA_ACCUM_SIZE,      0,
  171.       FXMESA_NONE
  172.     }
  173.   }
  174. };
  175. static int qt_pix = sizeof(pix) / sizeof(pix[0]);
  176.  
  177. static fxMesaContext ctx = NULL;
  178. static WNDPROC hWNDOldProc;
  179. static int curPFD = 0;
  180. static HDC hDC;
  181. static HWND hWND;
  182.  
  183. static GLboolean haveDualHead;
  184.  
  185. /* For the in-window-rendering hack */
  186.  
  187. static GLboolean   gdiWindowHack;
  188. static GLboolean   gdiWindowHackEna;
  189. static void        *dibSurfacePtr;
  190. static BITMAPINFO  *dibBMI;
  191. static HBITMAP     dibHBM;
  192. static HWND        dibWnd;
  193.  
  194. LONG APIENTRY __wglMonitor(HWND hwnd,UINT message,UINT wParam,LONG lParam)
  195.  
  196. {
  197.   long ret; /* Now gives the resized window at the end to hWNDOldProc */
  198.  
  199.   if(ctx && hwnd == hWND) {
  200.     switch(message) {
  201.     case WM_PAINT:
  202.     case WM_MOVE:
  203.           break;
  204.     case WM_DISPLAYCHANGE:
  205.     case WM_SIZE:
  206.       if (wParam != SIZE_MINIMIZED) {
  207.     static int moving = 0;
  208.     if (!moving) {
  209.       if(fxQueryHardware()!=GR_SSTTYPE_VOODOO) {
  210.         if(!grSstControl(GR_CONTROL_RESIZE)) {
  211.           moving = 1;
  212.           SetWindowPos(hwnd, 0, 0, 0, 300, 300, SWP_NOMOVE|SWP_NOZORDER);
  213.           moving = 0;
  214.           if(!grSstControl(GR_CONTROL_RESIZE)) {
  215.         /*MessageBox(0,_T("Error changing windowsize"),_T("fxMESA"),MB_OK);*/
  216.         PostMessage(hWND,WM_CLOSE,0,0);
  217.           }
  218.         }
  219.       }
  220.  
  221.       /* Do the clipping in the glide library */
  222.       grClipWindow(0,0,grSstScreenWidth(),grSstScreenHeight());
  223.       /* And let the new size set in the context */
  224.       fxMesaUpdateScreenSize(ctx);
  225.     }
  226.       }
  227.       break;
  228.     case WM_ACTIVATE:
  229.       if((fxQueryHardware()==GR_SSTTYPE_VOODOO) &&
  230.      (!gdiWindowHack) &&
  231.      (!haveDualHead)) {
  232.     WORD fActive = LOWORD(wParam);
  233.     BOOL fMinimized = (BOOL) HIWORD(wParam);
  234.  
  235.     if((fActive == WA_INACTIVE) || fMinimized)
  236.       grSstControl(GR_CONTROL_DEACTIVATE);
  237.     else
  238.       grSstControl(GR_CONTROL_ACTIVATE);
  239.       }
  240.       break;
  241.     case WM_SHOWWINDOW:
  242.       break;
  243.     case WM_SYSCHAR:
  244.       if(gdiWindowHackEna && (VK_RETURN == wParam)) {
  245.     if(gdiWindowHack) {
  246.       gdiWindowHack = GL_FALSE;
  247.       grSstControl(GR_CONTROL_ACTIVATE);
  248.     } else {
  249.       gdiWindowHack = GL_TRUE;
  250.       grSstControl(GR_CONTROL_DEACTIVATE);
  251.     }
  252.       }
  253.       break;
  254.     }
  255.   }
  256.  
  257.   /* Finaly call the hWNDOldProc, which handles the resize witch the
  258.      now changed window sizes */
  259.   ret = (hWNDOldProc)(hwnd,message,wParam,lParam);
  260.   return(ret);
  261. }
  262.  
  263. BOOL APIENTRY wglCopyContext(HGLRC hglrcSrc,HGLRC hglrcDst,UINT mask)
  264. {
  265.   return(FALSE);
  266. }
  267.  
  268. HGLRC APIENTRY wglCreateContext(HDC hdc)
  269. {
  270.   HWND hWnd;
  271.   WNDPROC oldProc;
  272.   int error;
  273.  
  274.   if(ctx) {
  275.     SetLastError(0);
  276.     return(NULL);
  277.   }
  278.  
  279.   if(!(hWnd = WindowFromDC(hdc))) {
  280.     SetLastError(0);
  281.     return(NULL);
  282.   }
  283.  
  284.   if(curPFD == 0) {
  285.     SetLastError(0);
  286.     return(NULL);
  287.   }
  288.  
  289.   if((oldProc = (WNDPROC)GetWindowLong(hWnd,GWL_WNDPROC)) != __wglMonitor) {
  290.     hWNDOldProc = oldProc;
  291.     SetWindowLong(hWnd,GWL_WNDPROC,(LONG)__wglMonitor);
  292.   }
  293.  
  294. #ifndef FX_SILENT
  295.   freopen("MESA.LOG","w",stderr);
  296. #endif
  297.  
  298.   ShowWindow(hWnd, SW_SHOWNORMAL);
  299.   SetForegroundWindow(hWnd);
  300.   Sleep(100); /* an hack for win95 */
  301.  
  302.   if(fxQueryHardware() == GR_SSTTYPE_VOODOO) {
  303.     RECT cliRect;
  304.  
  305.     GetClientRect(hWnd,&cliRect);
  306.     error = !(ctx = fxMesaCreateBestContext((GLuint)hWnd,cliRect.right,cliRect.bottom,
  307.                         pix[curPFD - 1].mesaAttr));
  308.  
  309.     if(!error) {
  310.       /* create the DIB section for windowed rendering */
  311.       DWORD *p;
  312.  
  313.       dibWnd = hWnd;
  314.  
  315.       hDC = GetDC(dibWnd);
  316.  
  317.       dibBMI = (BITMAPINFO*) malloc( sizeof(BITMAPINFO) + (256*sizeof(RGBQUAD)));
  318.  
  319.       memset(dibBMI,0,sizeof(BITMAPINFO) + (256*sizeof(RGBQUAD)));
  320.  
  321.       dibBMI->bmiHeader.biSize            = sizeof(BITMAPINFOHEADER);
  322.       dibBMI->bmiHeader.biWidth            = ctx->width;
  323.       dibBMI->bmiHeader.biHeight        = -ctx->height;
  324.       dibBMI->bmiHeader.biPlanes        = (short)1;
  325.       dibBMI->bmiHeader.biBitCount        = (short)16;
  326.       dibBMI->bmiHeader.biCompression        = BI_BITFIELDS;
  327.       dibBMI->bmiHeader.biSizeImage        = 0;
  328.       dibBMI->bmiHeader.biXPelsPerMeter            = 0;
  329.       dibBMI->bmiHeader.biYPelsPerMeter            = 0;
  330.       dibBMI->bmiHeader.biClrUsed        = 3;
  331.       dibBMI->bmiHeader.biClrImportant        = 3;
  332.  
  333.       p = (DWORD*)dibBMI->bmiColors;
  334.       p[0] = 0xF800;
  335.       p[1] = 0x07E0;
  336.       p[2] = 0x001F;
  337.  
  338.       dibHBM = CreateDIBSection(hDC, dibBMI, DIB_RGB_COLORS, &dibSurfacePtr, NULL, 0);
  339.  
  340.       ReleaseDC(dibWnd, hDC);
  341.  
  342.       gdiWindowHackEna = (dibHBM != NULL ? GL_TRUE : GL_FALSE);
  343.  
  344.       if (!getenv("MESA_WGL_FX") || !strcmp(getenv("MESA_WGL_FX"),"fullscreen"))
  345.     gdiWindowHack = GL_FALSE;
  346.       else {
  347.     gdiWindowHack = GL_TRUE;
  348.     grSstControl(GR_CONTROL_DEACTIVATE);
  349.       }
  350.     }
  351.   } else {
  352.     /* For the Voodoo Rush */
  353.  
  354.     if(getenv("MESA_WGL_FX") && !strcmp(getenv("MESA_WGL_FX"),"fullscreen")) {
  355.       RECT cliRect;
  356.  
  357.       GetClientRect(hWnd,&cliRect);
  358.       error = !(ctx = fxMesaCreateBestContext((GLuint)hWnd,cliRect.right,cliRect.bottom,
  359.                           pix[curPFD - 1].mesaAttr));
  360.     } else
  361.       error = !(ctx = fxMesaCreateContext((GLuint)hWnd,GR_RESOLUTION_NONE,GR_REFRESH_75Hz,
  362.                       pix[curPFD - 1].mesaAttr));
  363.   }
  364.  
  365.   if(getenv("SST_DUALHEAD"))
  366.     haveDualHead=((atoi(getenv("SST_DUALHEAD"))==1) ? GL_TRUE:GL_FALSE);
  367.   else
  368.     haveDualHead=GL_FALSE;
  369.  
  370.   if(error) {
  371.     SetLastError(0);
  372.     return(NULL);
  373.   }
  374.  
  375.   hDC = hdc;
  376.   hWND = hWnd;
  377.  
  378.   /* Required by the OpenGL Optimizer 1.1 (is it a Optimizer bug ?) */
  379.   wglMakeCurrent(hdc,(HGLRC)1);
  380.  
  381.   return((HGLRC)1);
  382. }
  383.  
  384. HGLRC APIENTRY wglCreateLayerContext(HDC hdc,int iLayerPlane)
  385. {
  386.   SetLastError(0);
  387.   return(NULL);
  388. }
  389.  
  390. BOOL APIENTRY wglDeleteContext(HGLRC hglrc)
  391. {
  392.   if(ctx && hglrc == (HGLRC)1) {
  393.     if (gdiWindowHackEna) {
  394.       DeleteObject(dibHBM);
  395.       free(dibBMI);
  396.  
  397.       dibSurfacePtr = NULL;
  398.       dibBMI = NULL;
  399.       dibHBM = NULL;
  400.       dibWnd = NULL;
  401.     }
  402.  
  403.     fxMesaDestroyContext(ctx);
  404.  
  405.     SetWindowLong(WindowFromDC(hDC),GWL_WNDPROC,(LONG)hWNDOldProc);
  406.  
  407.     ctx = NULL;
  408.     hDC = 0;
  409.     return(TRUE);
  410.   }
  411.  
  412.   SetLastError(0);
  413.  
  414.   return(FALSE);
  415. }
  416.  
  417. HGLRC APIENTRY wglGetCurrentContext(VOID)
  418. {
  419.   if(ctx)
  420.     return((HGLRC)1);
  421.  
  422.   SetLastError(0);
  423.   return(NULL);
  424. }
  425.  
  426. HDC APIENTRY wglGetCurrentDC(VOID)
  427. {
  428.   if(ctx)
  429.     return(hDC);
  430.  
  431.   SetLastError(0);
  432.   return(NULL);
  433. }
  434.  
  435. PROC APIENTRY wglGetProcAddress(LPCSTR lpszProc)
  436. {
  437.   int           i;
  438.  
  439.   /*fprintf(stderr,"fxMesa: looking for extension %s\n",lpszProc);
  440.     fflush(stderr);*/
  441.  
  442.   for(i = 0;i < qt_ext;i++)
  443.     if(!strcmp(lpszProc,ext[i].name)) {
  444.       /*fprintf(stderr,"fxMesa: found extension %s\n",lpszProc);
  445.     fflush(stderr);*/
  446.  
  447.       return(ext[i].proc);
  448.     }
  449.   SetLastError(0);
  450.   return(NULL);
  451. }
  452.  
  453. BOOL APIENTRY wglMakeCurrent(HDC hdc,HGLRC hglrc)
  454. {
  455.   if((hdc==NULL) && (hglrc==NULL))
  456.     return(TRUE);
  457.  
  458.   if(!ctx || hglrc != (HGLRC)1 || WindowFromDC(hdc) != hWND) {
  459.     SetLastError(0);
  460.     return(FALSE);
  461.   }
  462.  
  463.   hDC = hdc;
  464.  
  465.   fxMesaMakeCurrent(ctx);
  466.  
  467.   return(TRUE);
  468. }
  469.  
  470. BOOL APIENTRY wglShareLists(HGLRC hglrc1,HGLRC hglrc2)
  471. {
  472.   if(!ctx || hglrc1 != (HGLRC)1 || hglrc1 != hglrc2) {
  473.     SetLastError(0);
  474.     return(FALSE);
  475.   }
  476.  
  477.   return(TRUE);
  478. }
  479.  
  480. BOOL APIENTRY wglUseFontBitmaps(HDC fontDevice, DWORD firstChar, DWORD numChars, DWORD listBase)
  481. {
  482. #define VERIFY(a) a
  483.  
  484.   TEXTMETRIC metric;
  485.   BITMAPINFO *dibInfo;
  486.   HDC bitDevice;
  487.   COLORREF tempColor;
  488.   int i;
  489.  
  490.   VERIFY(GetTextMetrics(fontDevice, &metric));
  491.  
  492.   dibInfo = (BITMAPINFO *) calloc(sizeof(BITMAPINFO) + sizeof(RGBQUAD), 1);
  493.   dibInfo->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
  494.   dibInfo->bmiHeader.biPlanes = 1;
  495.   dibInfo->bmiHeader.biBitCount = 1;
  496.   dibInfo->bmiHeader.biCompression = BI_RGB;
  497.  
  498.   bitDevice = CreateCompatibleDC(fontDevice);
  499.   // HDC bitDevice = CreateDC("DISPLAY", NULL, NULL, NULL);
  500.   // VERIFY(bitDevice);
  501.  
  502.   // Swap fore and back colors so the bitmap has the right polarity
  503.   tempColor = GetBkColor(bitDevice);
  504.   SetBkColor(bitDevice, GetTextColor(bitDevice));
  505.   SetTextColor(bitDevice, tempColor);
  506.  
  507.   // Place chars based on base line
  508.   VERIFY(SetTextAlign(bitDevice, TA_BASELINE) >= 0);
  509.  
  510.   for(i = 0; i < numChars; i++) {
  511.       SIZE size;
  512.       char curChar;
  513.       int charWidth,charHeight,bmapWidth,bmapHeight,numBytes,res;
  514.       HBITMAP bitObject;
  515.       HGDIOBJ origBmap;
  516.       unsigned char *bmap;
  517.  
  518.       curChar = i + firstChar;
  519.  
  520.       // Find how high/wide this character is
  521.       VERIFY(GetTextExtentPoint32(bitDevice, &curChar, 1, &size));
  522.  
  523.       // Create the output bitmap
  524.       charWidth = size.cx;
  525.       charHeight = size.cy;
  526.       bmapWidth = ((charWidth + 31) / 32) * 32;   // Round up to the next multiple of 32 bits
  527.       bmapHeight = charHeight;
  528.       bitObject = CreateCompatibleBitmap(bitDevice,
  529.           bmapWidth,
  530.           bmapHeight);
  531.       //VERIFY(bitObject);
  532.  
  533.       // Assign the output bitmap to the device
  534.       origBmap = SelectObject(bitDevice, bitObject);
  535.       VERIFY(origBmap);
  536.  
  537.       VERIFY( PatBlt( bitDevice, 0, 0, bmapWidth, bmapHeight,BLACKNESS ) );
  538.  
  539.       // Use our source font on the device
  540.       VERIFY(SelectObject(bitDevice, GetCurrentObject(fontDevice,OBJ_FONT)));
  541.  
  542.       // Draw the character
  543.       VERIFY(TextOut(bitDevice, 0, metric.tmAscent, &curChar, 1));
  544.  
  545.       // Unselect our bmap object
  546.       VERIFY(SelectObject(bitDevice, origBmap));
  547.  
  548.       // Convert the display dependant representation to a 1 bit deep DIB
  549.       numBytes = (bmapWidth * bmapHeight) / 8;
  550.       bmap = malloc(numBytes);
  551.       dibInfo->bmiHeader.biWidth = bmapWidth;
  552.       dibInfo->bmiHeader.biHeight = bmapHeight;
  553.       res = GetDIBits(bitDevice, bitObject, 0, bmapHeight, bmap,
  554.           dibInfo,
  555.           DIB_RGB_COLORS);
  556.       //VERIFY(res);
  557.  
  558.       // Create the GL object
  559.       glNewList(i + listBase, GL_COMPILE);
  560.       glBitmap(bmapWidth, bmapHeight, 0.0, metric.tmDescent,
  561.            charWidth, 0.0,
  562.            bmap);
  563.       glEndList();
  564.       // CheckGL();
  565.  
  566.       // Destroy the bmap object
  567.       DeleteObject(bitObject);
  568.  
  569.       // Deallocate the bitmap data
  570.       free(bmap);
  571.   }
  572.  
  573.   // Destroy the DC
  574.   VERIFY(DeleteDC(bitDevice));
  575.  
  576.   free(dibInfo);
  577.  
  578.   return TRUE;
  579. #undef VERIFY
  580. }
  581.  
  582. BOOL APIENTRY wglUseFontBitmapsW(HDC hdc,DWORD first,DWORD count,DWORD listBase)
  583. {
  584.   return(FALSE);
  585. }
  586.  
  587. BOOL APIENTRY wglUseFontOutlinesA(HDC hdc,DWORD first,DWORD count,
  588.                                   DWORD listBase,FLOAT deviation,
  589.                                   FLOAT extrusion,int format,
  590.                                   LPGLYPHMETRICSFLOAT lpgmf)
  591. {
  592.   SetLastError(0);
  593.   return(FALSE);
  594. }
  595.  
  596. BOOL APIENTRY wglUseFontOutlinesW(HDC hdc,DWORD first,DWORD count,
  597.                                   DWORD listBase,FLOAT deviation,
  598.                                   FLOAT extrusion,int format,
  599.                                   LPGLYPHMETRICSFLOAT lpgmf)
  600. {
  601.   SetLastError(0);
  602.   return(FALSE);
  603. }
  604.  
  605.  
  606. BOOL APIENTRY wglSwapLayerBuffers(HDC hdc,UINT fuPlanes)
  607. {
  608.   if(ctx && WindowFromDC(hdc) == hWND) {
  609.     fxMesaSwapBuffers();
  610.  
  611.     return(TRUE);
  612.   }
  613.  
  614.   SetLastError(0);
  615.   return(FALSE);
  616. }
  617.  
  618. int APIENTRY wglChoosePixelFormat(HDC hdc,
  619.                                   CONST PIXELFORMATDESCRIPTOR *ppfd)
  620. {
  621.   int i,best=-1,qt_valid_pix;
  622.  
  623.   qt_valid_pix = qt_pix;
  624.  
  625.   if(ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR) || ppfd->nVersion != 1) {
  626.     SetLastError(0);
  627.     return(0);
  628.   }
  629.  
  630.   for(i = 0;i < qt_valid_pix;i++) {
  631.     if((ppfd->dwFlags & PFD_DRAW_TO_WINDOW) && !(pix[i].pfd.dwFlags & PFD_DRAW_TO_WINDOW))
  632.       continue;
  633.     if((ppfd->dwFlags & PFD_DRAW_TO_BITMAP) && !(pix[i].pfd.dwFlags & PFD_DRAW_TO_BITMAP))
  634.       continue;
  635.     if((ppfd->dwFlags & PFD_SUPPORT_GDI) && !(pix[i].pfd.dwFlags & PFD_SUPPORT_GDI))
  636.       continue;
  637.     if((ppfd->dwFlags & PFD_SUPPORT_OPENGL) && !(pix[i].pfd.dwFlags & PFD_SUPPORT_OPENGL))
  638.       continue;
  639.     if(!(ppfd->dwFlags & PFD_DOUBLEBUFFER_DONTCARE) &&
  640.        ((ppfd->dwFlags & PFD_DOUBLEBUFFER) != (pix[i].pfd.dwFlags & PFD_DOUBLEBUFFER)))
  641.       continue;
  642.     if(!(ppfd->dwFlags & PFD_STEREO_DONTCARE) &&
  643.        ((ppfd->dwFlags & PFD_STEREO) != (pix[i].pfd.dwFlags & PFD_STEREO)))
  644.       continue;
  645.  
  646.     if (ppfd->cDepthBits > 0 && pix[i].pfd.cDepthBits == 0)
  647.       continue; /* need depth buffer */
  648.  
  649.     if (ppfd->cAlphaBits > 0 && pix[i].pfd.cAlphaBits == 0)
  650.       continue; /* need alpha buffer */
  651.  
  652.     if(ppfd->iPixelType == pix[i].pfd.iPixelType) {
  653.       best = i + 1;
  654.       break;
  655.     }
  656.   }
  657.  
  658.   if(best == -1) {
  659.     SetLastError(0);
  660.     return(0);
  661.   }
  662.  
  663.   return(best);
  664. }
  665.  
  666. int APIENTRY ChoosePixelFormat(HDC hdc,
  667.                    CONST PIXELFORMATDESCRIPTOR *ppfd)
  668. {
  669.   return wglChoosePixelFormat(hdc,ppfd);
  670. }
  671.  
  672. int APIENTRY wglDescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes,
  673.                                     LPPIXELFORMATDESCRIPTOR ppfd)
  674. {
  675.   int qt_valid_pix;
  676.  
  677.   qt_valid_pix = qt_pix;
  678.  
  679.   if(iPixelFormat < 1 || iPixelFormat > qt_valid_pix ||
  680.     ((nBytes != sizeof(PIXELFORMATDESCRIPTOR)) && (nBytes != 0))) {
  681.     SetLastError(0);
  682.     return(0);
  683.   }
  684.  
  685.   if(nBytes != 0)
  686.     *ppfd = pix[iPixelFormat - 1].pfd;
  687.  
  688.   return(qt_valid_pix);
  689. }
  690.  
  691. int APIENTRY DescribePixelFormat(HDC hdc,int iPixelFormat,UINT nBytes,
  692.                  LPPIXELFORMATDESCRIPTOR ppfd)
  693. {
  694.   return wglDescribePixelFormat(hdc,iPixelFormat,nBytes,ppfd);
  695. }
  696.  
  697. int APIENTRY wglGetPixelFormat(HDC hdc)
  698. {
  699.   if(curPFD == 0) {
  700.     SetLastError(0);
  701.     return(0);
  702.   }
  703.  
  704.   return(curPFD);
  705. }
  706.  
  707. int APIENTRY GetPixelFormat(HDC hdc)
  708. {
  709.   return wglGetPixelFormat(hdc);
  710. }
  711.  
  712. BOOL APIENTRY wglSetPixelFormat(HDC hdc,int iPixelFormat,
  713.                                 CONST PIXELFORMATDESCRIPTOR *ppfd)
  714. {
  715.   int qt_valid_pix;
  716.  
  717.   qt_valid_pix = qt_pix;
  718.  
  719.   if(iPixelFormat < 1 || iPixelFormat > qt_valid_pix || ppfd->nSize != sizeof(PIXELFORMATDESCRIPTOR)) {
  720.     SetLastError(0);
  721.     return(FALSE);
  722.   }
  723.   curPFD = iPixelFormat;
  724.  
  725.   return(TRUE);
  726. }
  727.  
  728. BOOL APIENTRY wglSwapBuffers(HDC hdc)
  729. {
  730.   if(!ctx) {
  731.     SetLastError(0);
  732.     return(FALSE);
  733.   }
  734.  
  735.   fxMesaSwapBuffers();
  736.  
  737.   if(gdiWindowHack) {
  738.     GLuint width=ctx->width;
  739.     GLuint height=ctx->height;
  740.  
  741.     HDC hdcScreen      = GetDC(dibWnd);
  742.     HDC hdcDIBSection  = CreateCompatibleDC(hdcScreen);
  743.     HBITMAP holdBitmap = (HBITMAP) SelectObject(hdcDIBSection, dibHBM);
  744.  
  745.     grLfbReadRegion(GR_BUFFER_FRONTBUFFER, 0, 0,
  746.             width, height,
  747.             width * 2,
  748.             dibSurfacePtr);
  749.  
  750.     /* Since the hardware is configured for GR_COLORFORMAT_ABGR the pixel data is
  751.      * going to come out as BGR 565, which is reverse of what we need for blitting
  752.      * to screen, so we need to convert it here pixel-by-pixel (ick). This loop would NOT
  753.      * be required if the color format was changed to GR_COLORFORMAT_ARGB, but I do
  754.      * not know the ramifications of that, so this will work until that is resolved.
  755.      *
  756.      * This routine CRIES out for MMX implementation, however since that's not
  757.      * guaranteed to be running on MMX enabled hardware so I'm not going to do
  758.      * that. I'm just going to try to make a reasonably efficient C
  759.      * version. -TAJ
  760.      *
  761.      * This routine drops frame rate by <1 fps on a 200Mhz MMX processor with a 640x480
  762.      * display. Obviously, it's performance hit will be higher on larger displays and
  763.      * less on smaller displays. To support the window-hack display this is probably fine.
  764.      */
  765.     {
  766.         unsigned long *pixel = dibSurfacePtr;
  767.         unsigned long count = (width * height) / 2;
  768.  
  769.         while (count--)
  770.         {
  771.             *pixel++ = (*pixel & 0x07e007e0)          /* greens */
  772.                 | ((*pixel & 0xf800f800) >> 11) /* swap blues */
  773.                 | ((*pixel & 0x001f001f) << 11) /* swap reds */
  774.                 ;
  775.         }
  776.     }
  777.  
  778.     BitBlt(hdcScreen, 0, 0,
  779.        width, height,
  780.        hdcDIBSection,
  781.        0, 0, SRCCOPY);
  782.  
  783.     ReleaseDC(dibWnd, hdcScreen);
  784.     SelectObject(hdcDIBSection, holdBitmap);
  785.     DeleteDC(hdcDIBSection);
  786.   }
  787.  
  788.   return(TRUE);
  789. }
  790.  
  791. BOOL APIENTRY SetPixelFormat(HDC hdc, int iPixelFormat,
  792.                              CONST PIXELFORMATDESCRIPTOR *ppfd)
  793. {
  794.   return wglSetPixelFormat(hdc,iPixelFormat,ppfd);
  795. }
  796.  
  797. BOOL APIENTRY SwapBuffers(HDC hdc)
  798. {
  799.   return wglSwapBuffers(hdc);
  800. }
  801.  
  802. #endif /* FX */
  803.